package com.exec;

import com.alibaba.fastjson.JSONObject;
import com.tycmc.util.RedisUtil;
import com.util.DateUtil;
import com.util.DruidUtil;
import com.util.PropertiesUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import ty.pub.TransPacket;

import java.util.*;

/*
*设备最新状态
 */
public class VclLastDataController {
    /**
     * 设备最新状态数据
     * @param inputObject
     * @return
     */
    public  static String execLastData(com.tycmc.bean.InputObject inputObject)  {
        //判断inputObject中是否存在这个工况信息
        TransPacket transPacket= inputObject.getTransPacket();
        //获取基础数据
        Map<String,String> baseInfo=transPacket.getBaseInfoMap();
        //获取工况数据
        Map<String,Map<Long,String>>workStatusMap=transPacket.getWorkStatusMap();
        //信息生成时间工况编号
        String msgTimeNumber=PropertiesUtil.getStringPro("MsgTimeNumber");
        String VclLastData=PropertiesUtil.getStringPro("VclLastData");
        //获取信息生成时间
        long msgTime=MapUtils.getLong(baseInfo,msgTimeNumber);
        List<String> sqlList=new ArrayList<String>();
        Map<String,Object>mapLast=new HashMap<String,Object>();
        //redis中设备最新状态
        String EngineLastData=PropertiesUtil.getStringPro("EngineLastData");
        String vclId=transPacket.getDeviceId();
        vclId=vclId.substring(4,vclId.length());
        EngineLastData=EngineLastData.replace("VCLID",vclId);
        List<Object>redisLastData=RedisUtil.hgetWithpip(EngineLastData,new String[]{"MsgESL_tOilCons_MsgTime","MsgESL_tWorkTime_MsgTime","MsgESL_tIdeaOil_MsgTime","MsgESL_tIdeaWorkTime_MsgTime","MsgESL_VclSpeed_MsgTime","MsgESL_KeyState_MsgTime","MsgESL_EgnState_MsgTime","MsgESL_Lola_MsgTime"});
        //List<String>redisLastData=RedisUtil.hmget(EngineLastData,new String[]{"MsgESL_tOilCons_MsgTime","MsgESL_tWorkTime_MsgTime","MsgESL_tIdeaOil_MsgTime","MsgESL_tIdeaWorkTime_MsgTime","MsgESL_VclSpeed_MsgTime","MsgESL_KeyState_MsgTime","MsgESL_EgnState_MsgTime","MsgESL_Lola_MsgTime"});
        //油耗工况编号
        String EngineOil= PropertiesUtil.getStringPro("EngineOil");
        StringBuffer sbfInsert=new StringBuffer("insert into Msg_EquipmentState_Last(MsgESL_VCLID ");
        StringBuffer InsertValue=new StringBuffer("values("+vclId);
        StringBuffer sbfUpdate=new StringBuffer();
        String maxDateStr="1970-01-01 00:00:00";
        int i=0;
        String EngineOilValue_Last=getLastAvalidValue(EngineOil,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(EngineOilValue_Last)){
            mapLast.put("MsgESL_tOilCons",EngineOilValue_Last.split("_")[0]);
            mapLast.put("MsgESL_tOilCons_MsgTime",EngineOilValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_tOilCons,MsgESL_tOilCons_MsgTime");
            InsertValue.append(","+EngineOilValue_Last.split("_")[0]+",'"+EngineOilValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_tOilCons="+EngineOilValue_Last.split("_")[0]+",MsgESL_tOilCons_MsgTime='"+EngineOilValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,EngineOilValue_Last.split("_")[1]);
        }
        i++;
        //工作时长
        String EngineWorkTime=PropertiesUtil.getStringPro("EngineWorkTime");
        String EngineWorkTimeValue_Last=getLastAvalidValue(EngineWorkTime,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(EngineWorkTimeValue_Last)){
            mapLast.put("MsgESL_tWorkTime",EngineWorkTimeValue_Last.split("_")[0]);
            mapLast.put("MsgESL_tWorkTime_MsgTime",EngineWorkTimeValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_tWorkTime,MsgESL_tWorkTime_MsgTime");
            InsertValue.append(","+EngineWorkTimeValue_Last.split("_")[0]+",'"+EngineWorkTimeValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_tWorkTime="+EngineWorkTimeValue_Last.split("_")[0]+",MsgESL_tWorkTime_MsgTime='"+EngineWorkTimeValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,EngineWorkTimeValue_Last.split("_")[1]);
        }
        i++;
        //发动机怠速油耗
        String EngineIdeaOil=PropertiesUtil.getStringPro("EngineIdeaOil");
        String EngineIdeaOilValue_Last=getLastAvalidValue(EngineIdeaOil,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(EngineIdeaOilValue_Last)){
            mapLast.put("MsgESL_tIdeaOil",EngineIdeaOilValue_Last.split("_")[0]);
            mapLast.put("MsgESL_tIdeaOil_MsgTime",EngineIdeaOilValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_tIdeaOil,MsgESL_tIdeaOil_MsgTime");
            InsertValue.append(","+EngineIdeaOilValue_Last.split("_")[0]+",'"+EngineIdeaOilValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_tIdeaOil="+EngineIdeaOilValue_Last.split("_")[0]+",MsgESL_tIdeaOil_MsgTime='"+EngineIdeaOilValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,EngineIdeaOilValue_Last.split("_")[1]);
        }
        i++;
        //发动机怠速时长
        String EngineIdeaWorkTime=PropertiesUtil.getStringPro("EngineIdeaWorkTime");
        String EngineIdeaWorkTimeValue_Last=getLastAvalidValue(EngineIdeaWorkTime,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(EngineIdeaWorkTimeValue_Last)){
            mapLast.put("MsgESL_tIdeaWorkTime",EngineIdeaWorkTimeValue_Last.split("_")[0]);
            mapLast.put("MsgESL_tIdeaWorkTime_MsgTime",EngineIdeaWorkTimeValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_tIdeaWorkTime,MsgESL_tIdeaWorkTime_MsgTime");
            InsertValue.append(","+EngineIdeaWorkTimeValue_Last.split("_")[0]+",'"+EngineIdeaWorkTimeValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_tIdeaWorkTime="+EngineIdeaWorkTimeValue_Last.split("_")[0]+",MsgESL_tIdeaWorkTime_MsgTime='"+EngineIdeaWorkTimeValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,EngineIdeaWorkTimeValue_Last.split("_")[1]);
        }
        i++;
        //矿车速度
        String VclSpeed=PropertiesUtil.getStringPro("VclSpeed");
        String VclSpeedValue_Last=getLastAvalidValue(VclSpeed,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(VclSpeedValue_Last)){
            mapLast.put("MsgESL_VclSpeed",VclSpeedValue_Last.split("_")[0]);
            mapLast.put("MsgESL_VclSpeed_MsgTime",VclSpeedValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_VclSpeed,MsgESL_VclSpeed_MsgTime");
            InsertValue.append(","+VclSpeedValue_Last.split("_")[0]+",'"+VclSpeedValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_VclSpeed="+VclSpeedValue_Last.split("_")[0]+",MsgESL_VclSpeed_MsgTime='"+VclSpeedValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,VclSpeedValue_Last.split("_")[1]);
        }
        i++;
        //钥匙状态
        String KeySwitch=PropertiesUtil.getStringPro("KeySwitch");
        String KeySwitchValue_Last=getLastAvalidValue(KeySwitch,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(KeySwitchValue_Last)){
            String keyStat=null;
            //如下转换是因为数据库和协议中涉及的枚举值含义不同，协议中0 表示钥匙开
            if("0".equals(KeySwitchValue_Last.split("_")[0])){
                keyStat="1";
            }else if("1".equals(KeySwitchValue_Last.split("_")[0])){
                keyStat="0";
            }
            mapLast.put("MsgESL_KeyState",keyStat);
            mapLast.put("MsgESL_KeyState_MsgTime",KeySwitchValue_Last.split("_")[1]);
            sbfInsert.append(",MsgESL_KeyState,MsgESL_KeyState_MsgTime");
            InsertValue.append(","+keyStat+",'"+KeySwitchValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_KeyState="+keyStat+",MsgESL_KeyState_MsgTime='"+KeySwitchValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,KeySwitchValue_Last.split("_")[1]);
        }
        i++;
        //发动机转速
        String EngineRotateSpeed=PropertiesUtil.getStringPro("EngineRotateSpeed");
        String EngineRotateSpeedValue_Last=getLastAvalidValue(EngineRotateSpeed,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(EngineRotateSpeedValue_Last)){
            double zhuanSu=Double.parseDouble(EngineRotateSpeedValue_Last.split("_")[0]);
            int EngineRotateStanrand=PropertiesUtil.getintPro("EngineRotateStanrand");
            String MsgESL_EgnState="0";
            if(zhuanSu>EngineRotateStanrand){//发动机开
                MsgESL_EgnState="1";
                mapLast.put("MsgESL_EgnState_MsgTime",EngineRotateSpeedValue_Last.split("_")[1]);
            }else{
                MsgESL_EgnState="0";
                mapLast.put("MsgESL_EgnState_MsgTime",EngineRotateSpeedValue_Last.split("_")[1]);
            }
            mapLast.put("MsgESL_EgnState",MsgESL_EgnState);
            sbfInsert.append(",MsgESL_EgnState,MsgESL_EgnState_MsgTime");
            InsertValue.append(","+MsgESL_EgnState+",'"+EngineRotateSpeedValue_Last.split("_")[1]+"'");
            sbfUpdate.append(",MsgESL_EgnState="+MsgESL_EgnState+",MsgESL_EgnState_MsgTime='"+EngineRotateSpeedValue_Last.split("_")[1]+"'");
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,EngineRotateSpeedValue_Last.split("_")[1]);
        }
        i++;
        //位置信息
        String VclPstn=PropertiesUtil.getStringPro("VclPstn");
        String VclPstnValue_Last=getLastPstnAvalidValue(VclPstn,workStatusMap,msgTime,redisLastData.get(i)==null?null:String.valueOf(redisLastData.get(i)));
        if(StringUtils.isNotBlank(VclPstnValue_Last)){
            JSONObject pstnInfoObj=JSONObject.parseObject(VclPstnValue_Last.split("_")[0]);
            String MsgESL_La=MapUtils.getString(pstnInfoObj,"La");
            String MsgESL_Lo=MapUtils.getString(pstnInfoObj,"Lo");
            String MsgESL_Lola_MsgTime=MapUtils.getString(pstnInfoObj,"PstnTime");
            String MsgESL_GpsSpeed=MapUtils.getString(pstnInfoObj,"Speed");
            String MsgESL_Direction=MapUtils.getString(pstnInfoObj,"Direction");
            mapLast.put("MsgESL_La",MsgESL_La);
            mapLast.put("MsgESL_Lo",MsgESL_Lo);
            mapLast.put("MsgESL_Lola_MsgTime",MsgESL_Lola_MsgTime );
            sbfInsert.append(",MsgESL_La,MsgESL_Lo,MsgESL_Lola_MsgTime");
            InsertValue.append(","+MsgESL_La+","+MsgESL_Lo+",'"+MsgESL_Lola_MsgTime+"'");
            sbfUpdate.append(",MsgESL_La="+MsgESL_La+",MsgESL_Lo="+MsgESL_Lo+",MsgESL_Lola_MsgTime='"+MsgESL_Lola_MsgTime+"'");
            if(StringUtils.isNotBlank(MsgESL_GpsSpeed)){
                mapLast.put("MsgESL_GpsSpeed",MsgESL_GpsSpeed);
                sbfInsert.append(",MsgESL_GpsSpeed");
                InsertValue.append(","+MsgESL_GpsSpeed);
                sbfUpdate.append(",MsgESL_GpsSpeed="+MsgESL_GpsSpeed);
            }
            if(StringUtils.isNotBlank(MsgESL_Direction)){
                mapLast.put("MsgESL_Direction",MsgESL_Direction);
                mapLast.put("MsgESL_Direction_MsgTime",MsgESL_Lola_MsgTime);
                sbfInsert.append(",MsgESL_Direction,MsgESL_Direction_MsgTime");
                InsertValue.append(","+MsgESL_Direction+",'"+MsgESL_Lola_MsgTime+"'");
                sbfUpdate.append(",MsgESL_Direction="+MsgESL_Direction+",MsgESL_Direction_MsgTime='"+MsgESL_Lola_MsgTime+"'");
            }
            maxDateStr=DateUtil.CompareDateStr(maxDateStr,MsgESL_Lola_MsgTime);
        }
        i++;
        if(mapLast.size()>0){//设备最新状态
            //获取信息生成时间数据集合
            Map<String,Object>mapStatic=inputObject.getCacheMap();
            String theVclmsgTime=MapUtils.getString(mapStatic,vclId+"_"+VclLastData);
            //如果为空，直接存入缓存map中
            if(StringUtils.isBlank(theVclmsgTime)){
                mapStatic.put(vclId+"_"+VclLastData,DateUtil.getStrTime(msgTime,0));
                sqlList.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+VclLastData+")  " +
                        "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
            }else{//如果不为空
                //上下时间比较
                long lastVclmsgTime=Long.valueOf(DateUtil.getLongTime(theVclmsgTime));
                if(msgTime>=lastVclmsgTime){
                    mapStatic.put(vclId+"_"+VclLastData,DateUtil.getStrTime(msgTime,0));
                    sqlList.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+VclLastData+")  " +
                            "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
                }else{
                    //缓存数据
                    return null;
                }
            }
            RedisUtil.hsetWithpip(EngineLastData,mapLast);
            sbfInsert.append(",MsgESL_MsgTime)"+InsertValue+",'"+maxDateStr+"')ON DUPLICATE KEY UPDATE "+sbfUpdate.substring(1)+",MsgESL_MsgTime='"+maxDateStr+"';");
            sqlList.add(sbfInsert.toString());
            DruidUtil.batch(sqlList);
        }
        return null;
    }

    /**
     * 获取工况最新有效值
     * @param dutyNumber 工况编号
     * @param workStatusMap 工况值Map
     * @param msgTime 时间戳
     * @return
     */
    private static String getLastAvalidValue(String dutyNumber, Map<String,Map<Long,String>>workStatusMap,long msgTime,String oldTime){
        Map<Long,String>map=workStatusMap.get(dutyNumber);
        String valueLast="";
        String msgTimeLast="";
        if(MapUtils.isNotEmpty(map)){
            for(long times:map.keySet()){
                //参数采集时间
                String msgtimeGet= DateUtil.getStrTime(msgTime,times);
                //采集值
                String dutyValue= MapUtils.getString(map,times);
                if(StringUtils.isNotBlank(dutyValue)){
                    if(StringUtils.isNotBlank(msgTimeLast)){
                        //比较时间
                        if(DateUtil.CompareDate(msgtimeGet,msgTimeLast)){
                            valueLast=dutyValue;
                            msgTimeLast=msgtimeGet;
                        }
                    }else{
                        valueLast=dutyValue;
                        msgTimeLast=msgtimeGet;
                    }
                }
            }
            if(StringUtils.isBlank(valueLast)||StringUtils.isBlank(msgTimeLast)){
                return null;
            }else{
                if(StringUtils.isBlank(oldTime)||DateUtil.CompareDate(msgTimeLast,oldTime)){
                    return valueLast+"_"+msgTimeLast;
                }
            }
        }
        return null;
    }
    /**
     * 获取工况最新有效值
     * @param dutyNumber 工况编号
     * @param workStatusMap 工况值Map {"La":38.3,"Lo":103.25,"Speed":4,"Direction":5,"Satellite":10,"PstnTime":"2017-5-15 10:10:10","gpsIsLast":1}
     * @param msgTime 时间戳
     * @return
     */
    private static String getLastPstnAvalidValue(String dutyNumber, Map<String,Map<Long,String>>workStatusMap,long msgTime,String oldTime){
        Map<Long,String>map=workStatusMap.get(dutyNumber);
        String valueLast="";
        String msgTimeLast="";
        boolean isCompare=false;
        if(MapUtils.isEmpty(map)){
            return null;
        }
        if(map.size()>0){
            for(long times:map.keySet()){
                //参数采集时间
                String msgtimeGet= DateUtil.getStrTime(msgTime,times);
                //采集值
                String dutyValue= MapUtils.getString(map,times);
                if(StringUtils.isNotBlank(dutyValue)){
                    if(StringUtils.isNotBlank(msgTimeLast)){
                        //比较时间
                        if(DateUtil.CompareDate(msgtimeGet,msgTimeLast)){
                            isCompare=true;
                        }
                    }else{
                        isCompare=true;
                    }
                }
                if(isCompare==true){//开始比较json串中数据是否异常
                    valueLast=dutyValue;
                    msgTimeLast=msgtimeGet;
                    JSONObject job=JSONObject.parseObject(valueLast);
                    String lat=MapUtils.getString(job,"La");
                    String lng=MapUtils.getString(job,"Lo");
                    String PstnTime=MapUtils.getString(job,"PstnTime");
                    if(StringUtils.isNotBlank(lat)&&StringUtils.isNotBlank(lng)&&StringUtils.isNotBlank(PstnTime)){
                        if(StringUtils.isBlank(oldTime)||DateUtil.CompareDate(msgtimeGet,oldTime)){
                            valueLast=dutyValue;
                            msgTimeLast=msgtimeGet;
                            isCompare=false;
                        }
                    }
                }
            }
            if(StringUtils.isBlank(valueLast)||StringUtils.isBlank(msgTimeLast)){
                return null;
            }
            return valueLast+"_"+msgTimeLast;
        }
        return null;
    }
}
